library ieee;
use ieee.std_logic_1164.all;

library work;
use work.all;

entity fetch is
	port (	Jump, PCSrcM, clk, rst: in std_logic;
			PcBranchM: in std_logic_vector(31 downto 0);
        	InstrF, PCF, PCPlus4F: out std_logic_vector(31 downto 0));
end entity;

architecture fetch_arch of fetch is

	component adder
	port (	a, b : in std_logic_vector(31 downto 0);
			y	 : out std_logic_vector(31 downto 0));
    end component;
    component flopr
    port (  d		: in std_logic_vector(31 downto 0);
			rst,clk	: in std_logic;
        	q	: out std_logic_vector(31 downto 0));
    end component;
    component mux2
    port (d0, d1 : in std_logic_vector(31 downto 0);
               s : in std_logic;
               y : out std_logic_vector(31 downto 0));
    end component;
    component imem is
    port(a	: in  std_logic_vector(5 downto 0);
       	rd	: out std_logic_vector(31 downto 0));
    end component;
    
	signal PCnext, PC_plus, PCJump, PCPlus4F_in, InstrF_in, PCF_in: std_logic_vector(31 downto 0);

	begin
		mux_pc : mux2 port map (d0 => PCPlus4F_in, d1 => PCBranchM, s => PCSrcM, y => PCNext);

		PCJump <= PCPlus4F_in(31 downto 28) & InstrF_in(25 downto 0) & "00";

        PCPlus4F <= PCPlus4F_in;
        InstrF <= InstrF_in;
        PCF <= PCF_in;

		mux_jump : mux2 port map (d0 => PCNext, d1 => PCJump, s => Jump, y => PC_plus);

		flopr_pc : flopr port map (d => PC_plus, rst => rst, clk => clk, q => PCF_in);

		imem_F : imem port map (a => PCF_in(5 downto 0), rd => InstrF_in);

		adder_F : adder port map (a => PCF_in, b => x"00000004", y => PCPlus4F);
end architecture;
